from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from decorator.decorator import check_login
from goods.models import Good
import redis
# Create your views here.


# 购物车视图
class CartAPIView(APIView):

    @check_login
    def post(self,request):

        # 1.获取用户对象
        user = request.user
        # 2.获取 商品的 productID
        good_id = request.data.get("productID")
        good_id = str(good_id)  # 将整形的id 转换为字符串
        # 3.根据商品id 查询商品对象
        good = Good.objects.get(id=good_id)
        # 4.判断库存,即good.stock > 0 ？

        # 若 good.stock > 0, 允许正常加购
        if good.stock > 0:
            # 连接redis
            redis_conn = redis.Redis(host="localhost", port=6379, db=0, password='123')
            cart_key = "cart:%s" % user.id
            print("当前用户的id", user.id)
            cart_selected_key = "cart_selected:%s" % user.id

            # 判断当前商品是否在用户的购物车
            history_good_id = redis_conn.hkeys(cart_key)
            print("查看历史购物车：", history_good_id)

            if good_id.encode() not in history_good_id:
                # 不在，则存入hash 对应的商品数量为1，并返回200
                redis_conn.hset(cart_key, good_id, 1)
                redis_conn.sadd(cart_selected_key, good_id)
                redis_conn.close()

                # 返回200的响应
                cart_data = {
                        "code": 200,
                        "msg": "新加入购物车成功",
                        "shoppingCartData": {
                        'id': cart_key, # 购物车id
                        'productID': good.id, # 商品id
                        'productName': good.sku_name, # 商品名称
                        'productImg': good.img, # 商品图片
                        'price': good.price, # 商品价格
                        'num': 1, # 加购的商品数量
                        'maxNum': good.stock, # 商品限购数量
                        'check': True # 是否勾选
                    }}
                return Response(cart_data)
            else:
                # 商品已经在购物车，将数量直接+1
                count = int(redis_conn.hget(cart_key, good_id).decode())
                count += 1

            # 注意判断当前加购商品count <= good.stock?    并返回{"code":201, "msg":"该商品已经在购物车，数量+1"}
            if count <= good.stock:
                redis_conn.hincrby(cart_key, good_id, 1)
                return Response({"code":201, "msg":"该商品已经在购物车，数量+1"})
            # 否则，返回{"code":202, "msg":"加购达到限制数量"}
            else:
                return Response({"code":202, 'msg':'加购达到限购数量！'})


        # 否则 就不能加购，并返回响应{"code":203,"msg":"库存不足，无法购买！"}
        else:
            return Response({'code':203, "msg":"库存不足，无法购买！"})


    @check_login
    def get(self, request):

        # 1.获取用户对象
        user = request.user
        # 2.把key构造出来， 连接redis
        cart_key = 'cart:%s' % user.id
        cart_selected_key = "cart_selected:%s" % user.id
        redis_coon = redis.Redis(host='localhost', port=6379, db=0, password='123')
        # 3.查询hash & set 中的数据
        cart_data = redis_coon.hgetall(cart_key)
        # 对cart_data中字节串进行解码
        cart_data_decode = {k.decode():v.decode() for k,v in cart_data.items()}

        cart_selected_data = redis_coon.smembers(cart_selected_key)
        # 对cart_selected_data中的字节串解码
        cart_selected_data_decode = [i.decode() for i in cart_selected_data]

        # print("购物车数据:", cart_key)
        # print("选中的数据:", cart_selected_key)

        # 4.组织每个商品的字典结构
        shoppingCartData = []
        for good_id, count in cart_data_decode.items():
            if good_id in cart_selected_data_decode:
                check = True
            else:
                check = False
            # 定义一个函数get_on_good,  在函数内部组织该good_id商品的  字典结构
            temp = self.get_one_good(cart_key, good_id, count, check=check)
            shoppingCartData.append(temp)


            # 最终的响应{"code":200,'msg':"加载用户购物车数据成功","shoppingCartData":[]}
        return Response({
            "code":200,
            "msg":"加载用户购物车数据成功",
            "shoppingCartData": shoppingCartData
        })

    @staticmethod
    def get_one_good(cart_key, good_id, count, check=False):
        # 构造  购物车中每一商品的字典结构{
        #     'id': cart_key,  # 购物车id
        #     'productID': good.id,  # 商品id
        #     'productName': good.sku_name,  # 商品名称
        #     'productImg': good.img,  # 商品图片
        #     'price': good.price,  # 商品价格
        #     'num': 1,  # 加购的商品数量
        #     'maxNum': good.stock,  # 商品限购数量
        #     'check': True  # 是否勾选
        # }

        # 查询商品对象
        try:
            good = Good.objects.get(id=good_id)
        except:
            return {}

        # 开始组织字典
        good_dict = {
                'id': cart_key,  # 购物车id
                'productID': good.id,  # 商品id
                'productName': good.sku_name,  # 商品名称
                'productImg': good.img,  # 商品图片
                'price': good.price,  # 商品价格
                'num': int(count),  # 加购的商品数量
                'maxNum': good.stock,  # 商品限购数量
                'check': check  # 是否勾选
        }
        return good_dict

    @check_login
    def put(self,request):   # 更新购物车

        # 1.获取用户对象，并构造key
        user = request.user
        cart_key = "cart:%s"%user.id
        cart_selected_key = "cart_selected:%s"%user.id

        # 2.获取前端数据 productID,num
        good_id = request.data.get("productID")
        count = request.data.get("num")

        # 3.连接redis数据库  并进行更新
        redis_conn = redis.Redis(host='localhost', port=6379, db=0, password='123')

        # 更新商品数量
        redis_conn.hset(cart_key, good_id, count)

        # 更新商品为选中状态
        redis_conn.sadd(cart_selected_key, good_id)

        redis_conn.close()

        # 4.返回响应
        return Response({'code':200, 'msg':'购物车商品更新成功'})

    @check_login
    # 删除购物车里面的商品
    def delete(self,request):
        # 1.获取前端的用户信息, key
        user = request.user
        cart_key = "cart:%s" % user.id
        cart_selected_key = "cart_selected%s" % user.id

        # 2.获取前端数据productID
        good_id = request.data.get("productID")

        # 3.连接redis,进行删除商品
        redis_conn = redis.Redis(host='localhost', port=6379, db=0, password='123')
        # 删除购物车的商品
        redis_conn.hdel(cart_key, good_id)
        redis_conn.srem(cart_selected_key, good_id)

        # 关闭redis连接 返回响应
        redis_conn.close()
        return Response({'code':200, 'msg':'删除商品成功！'})


# 商品的勾选状态视图类
class CartSelection(APIView):

    # 商品的取消单选
    @check_login
    def put(self,request):
        # 1.获取用户对象， 构造key
        user = request.user
        cart_selected_key = "cart_selected:%s" % user.id

        # 2.获取前端数据， productID, val
        good_id = request.data.get("productID")
        val = request.data.get('val')

        # 3.更新当前商品的选中状态
        redis_conn = redis.Redis(host='localhost', port=6379, db=0, password='123')
        if val:
            redis_conn.sadd(cart_selected_key, good_id)
        else:
            redis_conn.srem(cart_selected_key, good_id)

        return Response({'code':200, 'msg':'%s成功'%("勾选" if val else "取消")})


    @check_login
    # 商品的全选与取消全选
    def post(self,request):

        # 1.获取用户对象， 构造key
        user = request.user
        cart_key = "cart:%s" % user.id
        cart_selected_key = "cart_selected%s" % user.id
        # 2.获取前端数据 val
        val = request.data.get("val")
        print("val:", val, type(val))

        # 3.更新全选的状态
        redis_conn = redis.Redis(host='localhost', port=6379, db=0, password='123')

        if val:
            # 全部勾选， 获取所有的商品id
            good_ids = redis_conn.hkeys(cart_key)

            # 所有的商品id，  放入集合中
            redis_conn.sadd(cart_selected_key, *good_ids)
        else:
            # 全部取消全选
            redis_conn.delete(cart_selected_key)

        # 4.返回响应
        return Response({'code':200})
